package controller

import (
	"net/http"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/errors"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/auth"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// ReceiptController 收款明细控制器
type ReceiptController struct {
	db *gorm.DB
}

// NewReceiptController 创建收款明细控制器
func NewReceiptController() *ReceiptController {
	return &ReceiptController{
		db: database.DB,
	}
}

// buildBaseQuery 构建基础查询，避免重复代码
func (c *ReceiptController) buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr string) *gorm.DB {
	query := c.db.Model(&models.AdminTransferRecord{}).
		Where("platform_account = ?", matrixAccount)

	// 添加筛选条件
	if status != "" {
		query = query.Where("status = ?", status)
	}
	if transferType != "" {
		query = query.Where("transfer_type = ?", transferType)
	}
	if currency != "" {
		query = query.Where("currency = ?", currency)
	}
	if startTimeStr != "" {
		startTime, _ := time.Parse("2006-01-02", startTimeStr)
		query = query.Where("created_at >= ?", startTime)
	}
	if endTimeStr != "" {
		endTime, _ := time.Parse("2006-01-02", endTimeStr)
		// 将结束时间设置为当天的23:59:59
		endTime = endTime.Add(24*time.Hour - time.Second)
		query = query.Where("created_at <= ?", endTime)
	}

	return query
}

// getMatrixAccountFromToken 从token中获取matrixAccount信息
func (c *ReceiptController) getMatrixAccountFromToken(ctx *gin.Context) (string, error) {
	// 从中间件中获取claims
	claims, exists := ctx.Get("claims")
	if !exists {
		return "", errors.NewAppError(http.StatusUnauthorized, "unauthorized", nil)
	}

	// 类型断言
	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		return "", errors.NewAppError(http.StatusInternalServerError, "invalid_token_claims", nil)
	}

	// 从claims中获取用户ID
	userID := authClaims.UserID

	// 首先检查用户是否存在
	var user models.User
	if err := c.db.First(&user, userID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return "", errors.NewAppError(http.StatusNotFound, "user_not_found", nil)
		}
		return "", errors.NewAppError(http.StatusInternalServerError, "database_error", err)
	}

	// 查询用户的Matrix账户信息
	var matrixAccount models.UserMatrixAccount
	if err := c.db.Where("user_id = ? AND status = 'active'", userID).First(&matrixAccount).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return "", errors.NewAppError(http.StatusNotFound, "matrix_account_not_found", nil)
		}
		return "", errors.NewAppError(http.StatusInternalServerError, "database_error", err)
	}

	return matrixAccount.MatrixAccount, nil
}

// GetReceiptDetails 获取收款明细列表
func (c *ReceiptController) GetReceiptDetails(ctx *gin.Context) {
	// 获取matrix_account
	matrixAccount, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		common.Error(ctx, http.StatusUnauthorized, "get_matrix_account_failed", err)
		return
	}

	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("pageIndex", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	// 获取筛选参数
	status := ctx.Query("status")
	transferType := ctx.Query("transfer_type")
	currency := ctx.Query("currency")
	startTimeStr := ctx.Query("start_time")
	endTimeStr := ctx.Query("end_time")

	// 构建查询
	query := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)

	// 获取总记录数
	var total int64
	if err := query.Count(&total).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "count_records_failed", err)
		return
	}

	// 分页查询
	var records []models.AdminTransferRecord
	offset := (page - 1) * pageSize
	if err := query.Preload("Admin", func(db *gorm.DB) *gorm.DB {
		return db.Select("id, username, phone, email")
	}).Offset(offset).
		Limit(pageSize).
		Order("created_at DESC").
		Find(&records).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "query_records_failed", err)
		return
	}

	// 计算统计信息
	var stats struct {
		TotalAmount    float64 `json:"total_amount"`
		TotalInAmount  float64 `json:"total_in_amount"`
		TotalOutAmount float64 `json:"total_out_amount"`
		SuccessCount   int64   `json:"success_count"`
		FailedCount    int64   `json:"failed_count"`
		PendingCount   int64   `json:"pending_count"`
	}

	// 获取转入金额统计（只计算成功的）
	transferInQuery := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)
	if err := transferInQuery.Where("transfer_type = ? AND status = ?", "transfer_in", "success").
		Select("COALESCE(SUM(transfer_amount), 0) as total_in_amount").Scan(&stats.TotalInAmount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_in_amount_failed", err)
		return
	}

	// 获取转出金额统计（只计算成功的）
	transferOutQuery := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)
	if err := transferOutQuery.Where("transfer_type = ? AND status = ?", "transfer_out", "success").
		Select("COALESCE(SUM(transfer_amount), 0) as total_out_amount").Scan(&stats.TotalOutAmount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_out_amount_failed", err)
		return
	}

	// 计算总金额（净额）：总转入 - 总转出（只计算成功的）
	stats.TotalAmount = stats.TotalInAmount - stats.TotalOutAmount

	// 获取状态统计
	successQuery := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)
	if err := successQuery.Where("status = ?", "success").Count(&stats.SuccessCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_success_count_failed", err)
		return
	}

	failedQuery := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)
	if err := failedQuery.Where("status = ?", "failed").Count(&stats.FailedCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_failed_count_failed", err)
		return
	}

	processingQuery := c.buildBaseQuery(matrixAccount, status, transferType, currency, startTimeStr, endTimeStr)
	if err := processingQuery.Where("status = ?", "processing").Count(&stats.PendingCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_pending_count_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"records": records,
		"pagination": gin.H{
			"page":      page,
			"page_size": pageSize,
			"total":     total,
			"pages":     (total + int64(pageSize) - 1) / int64(pageSize),
		},
		"statistics":     stats,
		"matrix_account": matrixAccount,
	})
}

// GetReceiptSummary 获取收款汇总统计
func (c *ReceiptController) GetReceiptSummary(ctx *gin.Context) {
	// 获取matrix_account
	matrixAccount, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		common.Error(ctx, http.StatusUnauthorized, "get_matrix_account_failed", err)
		return
	}

	// 获取时间范围参数
	startTimeStr := ctx.DefaultQuery("start_time", time.Now().AddDate(0, 0, -30).Format("2006-01-02"))
	endTimeStr := ctx.DefaultQuery("end_time", time.Now().Format("2006-01-02"))

	startTime, err := time.Parse("2006-01-02", startTimeStr)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_start_time", err)
		return
	}

	endTime, err := time.Parse("2006-01-02", endTimeStr)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_end_time", err)
		return
	}
	// 将结束时间设置为当天的23:59:59
	endTime = endTime.Add(24*time.Hour - time.Second)

	// 构建基础查询
	query := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)

	// 获取总体统计
	var totalStats struct {
		TotalRecords   int64   `json:"total_records"`
		TotalAmount    float64 `json:"total_amount"`
		TotalInAmount  float64 `json:"total_in_amount"`
		TotalOutAmount float64 `json:"total_out_amount"`
		SuccessCount   int64   `json:"success_count"`
		FailedCount    int64   `json:"failed_count"`
		PendingCount   int64   `json:"pending_count"`
	}

	if err := query.Count(&totalStats.TotalRecords).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_records_failed", err)
		return
	}

	if err := query.Select("COALESCE(SUM(transfer_amount), 0) as total_amount").Scan(&totalStats.TotalAmount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_amount_failed", err)
		return
	}

	// 获取转入金额统计
	transferInQuery := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)
	if err := transferInQuery.Where("transfer_type = ?", "transfer_in").
		Select("COALESCE(SUM(transfer_amount), 0) as total_in_amount").Scan(&totalStats.TotalInAmount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_in_amount_failed", err)
		return
	}

	// 获取转出金额统计
	transferOutQuery := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)
	if err := transferOutQuery.Where("transfer_type = ?", "transfer_out").
		Select("COALESCE(SUM(transfer_amount), 0) as total_out_amount").Scan(&totalStats.TotalOutAmount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_total_out_amount_failed", err)
		return
	}

	// 获取状态统计
	successQuery := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)
	if err := successQuery.Where("status = ?", "success").Count(&totalStats.SuccessCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_success_count_failed", err)
		return
	}

	failedQuery := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)
	if err := failedQuery.Where("status = ?", "failed").Count(&totalStats.FailedCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_failed_count_failed", err)
		return
	}

	processingQuery := c.buildBaseQuery(matrixAccount, "", "", "", startTimeStr, endTimeStr)
	if err := processingQuery.Where("status = ?", "processing").Count(&totalStats.PendingCount).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_pending_count_failed", err)
		return
	}

	// 获取每日统计
	type DailyStats struct {
		Date         string  `json:"date"`
		TotalAmount  float64 `json:"total_amount"`
		InAmount     float64 `json:"in_amount"`
		OutAmount    float64 `json:"out_amount"`
		RecordCount  int64   `json:"record_count"`
		SuccessCount int64   `json:"success_count"`
		FailedCount  int64   `json:"failed_count"`
	}

	var dailyStats []DailyStats
	dailySQL := `
		SELECT 
			DATE(created_at) as date,
			COALESCE(SUM(transfer_amount), 0) as total_amount,
			COALESCE(SUM(CASE WHEN transfer_type = 'transfer_in' THEN transfer_amount ELSE 0 END), 0) as in_amount,
			COALESCE(SUM(CASE WHEN transfer_type = 'transfer_out' THEN transfer_amount ELSE 0 END), 0) as out_amount,
			COUNT(*) as record_count,
			SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as success_count,
			SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_count
		FROM admin_transfer_records 
		WHERE platform_account = ? AND created_at BETWEEN ? AND ?
		GROUP BY DATE(created_at)
		ORDER BY date DESC
	`

	if err := c.db.Raw(dailySQL, matrixAccount, startTime, endTime).Scan(&dailyStats).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_daily_stats_failed", err)
		return
	}

	// 获取货币统计
	type CurrencyStats struct {
		Currency    string  `json:"currency"`
		TotalAmount float64 `json:"total_amount"`
		RecordCount int64   `json:"record_count"`
	}

	var currencyStats []CurrencyStats
	currencySQL := `
		SELECT 
			currency,
			COALESCE(SUM(transfer_amount), 0) as total_amount,
			COUNT(*) as record_count
		FROM admin_transfer_records 
		WHERE platform_account = ? AND created_at BETWEEN ? AND ?
		GROUP BY currency
		ORDER BY total_amount DESC
	`

	if err := c.db.Raw(currencySQL, matrixAccount, startTime, endTime).Scan(&currencyStats).Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_currency_stats_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"total_statistics":    totalStats,
		"daily_statistics":    dailyStats,
		"currency_statistics": currencyStats,
		"query_params": gin.H{
			"start_time":     startTimeStr,
			"end_time":       endTimeStr,
			"matrix_account": matrixAccount,
		},
	})
}

// GetReceiptDetail 获取单条收款明细详情
func (c *ReceiptController) GetReceiptDetail(ctx *gin.Context) {
	// 获取matrix_account
	matrixAccount, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		common.Error(ctx, http.StatusUnauthorized, "get_matrix_account_failed", err)
		return
	}

	// 获取记录ID
	recordID := ctx.Param("id")
	if recordID == "" {
		common.Error(ctx, http.StatusBadRequest, "record_id_required", nil)
		return
	}

	// 查询记录详情
	var record models.AdminTransferRecord
	if err := c.db.Preload("Admin", func(db *gorm.DB) *gorm.DB {
		return db.Select("id, username, phone, email")
	}).Where("id = ? AND platform_account = ?", recordID, matrixAccount).
		First(&record).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "record_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "query_record_failed", err)
		}
		return
	}

	common.Success(ctx, record)
}
